import React, { PureComponent } from 'react';
import moment from 'moment';
import { connect } from 'dva';
import { DownOutlined, PlusOutlined } from '@ant-design/icons';
import '@ant-design/compatible/assets/index.css';
import { Form, Row, Card, message, Tabs, DatePicker, Select, Menu, Dropdown, Divider } from 'antd';
import queryString from 'query-string';
import HOCTableList from '@/HOC/TableList';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import HOCSelect from '@/components/AntDesign/Select';
import Area from '@/pages/components/Area';
import Customer from '@/pages/components/Customer';
import TextOverFlow from '@/pages/components/TextOverFlow';
import SearchPersonEs from '@/pages/components/SearchPersonEs';
import styles from '@/utils/utils.less';
import { checkPermissions } from '@/utils/authority';
import { allocationList, getAllotRuleList } from '@/services/careermange';

import TabPanel from './TabPanel/Index';
import AllocationModal from './AllocationModal';
import AutoModal from './AutoModal';
import DetailModal from './DetailModal';
import { allocConfirm, deleteConfirm, receiveConfirm, unAllocConfirm } from './AllocationConfirm';

const { RangePicker } = DatePicker;
const { TabPane } = Tabs;
const { Option } = Select;

@connect(({ allocation, loading }) => ({
  allocation,
  loading: loading.models.allocation,
  autoRuleLoading:
    loading.effects['allocation/addAllotRule'] || loading.effects['allocation/modifyAllotRule'],
}))
@HOCTableList({ namespace: 'allocation' })
class TableList extends PureComponent {
  formRef = React.createRef();

  async componentDidMount() {
    const {
      location,
      dispatch,
      allocation: {
        tableList: {
          pagination: { current, pageSize },
        },
        tab: { activeKey: defaultActiveKey },
      },
    } = this.props;
    const activeKey = queryString.parse(location.search).activeKey || defaultActiveKey;
    await dispatch({
      type: 'allocation/setTabActiveKey',
      payload: { activeKey },
    });
    // 因为model是初始化时就生成好了当时权限并未初始化，需要再进入后再处理一下
    await dispatch({
      type: 'allocation/setTLTabList',
      payload: {
        list: checkPermissions('es:allotRule:pageListAllotRule')
          ? [
              { itemName: '待分配', itemCode: '2', showOrder: 1 },
              { itemName: '已分配', itemCode: '1', showOrder: 2 },
              { itemName: '自动分配', itemCode: '3', showOrder: 3 },
            ]
          : [
              { itemName: '待分配', itemCode: '2', showOrder: 1 },
              { itemName: '已分配', itemCode: '1', showOrder: 2 },
            ],
      },
    });
    // 获取领取列表
    dispatch({
      type: 'allocation/userList',
      payload: {},
    });
    // 获取签约方列表
    dispatch({
      type: 'allocation/getSuppList',
      payload: { name: null },
    });
    // 获取员工服务人员下拉;
    dispatch({
      type: 'allocation/listEs',
      payload: { roleIds: ['BR0000000098'] }, // 入参是固定的
    });
    // 获取服务客服下拉
    dispatch({
      type: 'allocation/listCs',
      payload: { roleIds: ['BS0000000090', 'BAR000000099', 'BAR0000000201'] },
    });
    // 获取分配服务客户下拉
    dispatch({
      type: 'allocation/listCustinfo',
      payload: {},
    });

    this.handleSearch(current, pageSize);
  }

  // 领取
  getType = () => {
    const {
      dispatch,
      allocation: {
        tableList,
        tab: { activeKey },
      },
    } = this.props;
    const { total, current, pageSize } = tableList.pagination;
    const selectedRows = tableList.selectedRows;
    const fieldsValue = this.formRef.current.getFieldsValue();

    const formFieldsValue = this.getDateParam(fieldsValue);
    if (total) {
      receiveConfirm(selectedRows.length, async () => {
        let arr = [];
        if (selectedRows.length) {
          arr = selectedRows.map(item => ({ entryId: item.entryId, vno: item.vno }));
        }
        const values = {
          entryList: arr,
          entryInfoQueryDto: {
            asgnState: activeKey,
            ...formFieldsValue,
          },
        };
        const response = await dispatch({
          type: 'allocation/receiveEntry',
          payload: values,
        });
        if (response.success) {
          message.success('领取成功！');
          this.handleSearch(current, pageSize);
        }
      });
    } else {
      message.warning('没有数据可以领取');
    }
  };

  // 分配
  getAllocats = () => {
    const {
      allocation: { tableList },
    } = this.props;
    const { total } = tableList.pagination;
    const { selectedRows } = tableList;

    if (total) {
      allocConfirm(selectedRows.length, () => {
        this.dispatchVisible(true);
      });
    } else {
      message.warning('没有数据可以分配');
    }
  };

  // 入参修改
  getDateParam = values => {
    const tempFieldsValue = {};

    Object.keys(values).forEach(key => {
      if (values[key] instanceof Array) {
        if (key === 'dateArr') {
          tempFieldsValue.startDate =
            (values.dateArr && values.dateArr[0] && values.dateArr[0].valueOf()) || null;
          tempFieldsValue.endDate =
            (values.dateArr && values.dateArr[1] && values.dateArr[1].valueOf()) || null;
        } else if (key === 'sendSuppIds') {
          tempFieldsValue[key] = values[key] === undefined ? null : values[key];
        }
      } else if (values[key] instanceof Object) {
        tempFieldsValue[key] = values[key].value;
      } else {
        tempFieldsValue[key] = values[key] === undefined ? null : values[key]?.trim();
      }
    });
    return tempFieldsValue;
  };

  getTableColumns = () => {
    const { activeKey: tabKey } = this.props.allocation.tab;
    const diffShow = Number(tabKey) === 2 ? styles.hide : styles.show;
    const diffShowDiff = Number(tabKey) === 1 ? styles.hide : styles.show;
    const moreMenu = record => (
      <Menu>
        <Menu.Item key="update" onClick={() => this.updateRule(record)}>
          修改
        </Menu.Item>

        <Menu.Item key="del" onClick={() => this.delRule(record)}>
          删除
        </Menu.Item>
      </Menu>
    );
    const columns = [
      {
        title: '员工姓名',
        dataIndex: 'empName',
        onHeaderCell: () => ({
          style: {
            fontWeight: 'bold',
          },
        }),
        render: text => <span>{text}</span>,
      },
      {
        title: '证件号',
        dataIndex: 'certNo',
        onCell: () => ({
          style: {
            textAlign: 'center',
          },
        }),
        onHeaderCell: () => ({
          style: {
            textAlign: 'center',
            fontWeight: 'bold',
            width: 170,
          },
        }),
      },
      {
        title: '客户名称',
        dataIndex: 'custName',
        onHeaderCell: () => ({
          style: {
            fontWeight: 'bold',
          },
        }),
        render: text => <TextOverFlow text={text} />,
      },
      {
        title: '执行地',
        dataIndex: 'areaName',
        onHeaderCell: () => ({
          style: {
            fontWeight: 'bold',
          },
        }),
      },
      {
        title: '所属客服',
        dataIndex: 'creName',
        onHeaderCell: () => ({
          style: {
            fontWeight: 'bolder',
          },
        }),
      },
      {
        title: '分配方式',
        dataIndex: 'asgnTypeName',
        className: diffShow,
        onCell: () => ({
          style: {
            textAlign: 'center',
          },
        }),
        onHeaderCell: () => ({
          style: {
            textAlign: 'center',
            fontWeight: 'bold',
          },
        }),
        render: (text, record) => {
          if (record.asgnTypeName) {
            return <span>{record.asgnTypeName}</span>;
          }
          return <span>---</span>;
        },
      },
      {
        title: '办理人',
        /* 谁办理的 */
        className: diffShow,
        dataIndex: 'tskName',
        onHeaderCell: () => ({
          style: {
            fontWeight: 'bold',
          },
        }),
        render: (text, record) => {
          let name;
          if (record.tskName != null) {
            name = record.tskName;
          } else {
            name = '--';
          }
          return <span>{name}</span>;
        },
      },
      {
        title: '进待分配时间',
        dataIndex: 'creTime',
        className: diffShowDiff,
        // sorter: (a, b) => new Date(b.creTime) - new Date(a.creTime),
        sorter: true,
        onCell: () => ({
          style: {
            textAlign: 'center',
          },
        }),
        onHeaderCell: () => ({
          style: {
            textAlign: 'center',
            fontWeight: 'bold',
          },
        }),
        render: (text, record) => {
          let name;
          if (record.creTime != null) {
            name = moment(record.creTime).format('YYYY-MM-DD HH:mm');
          } else {
            name = '--';
          }
          return <span>{name}</span>;
        },
      },
      {
        title: '分配领取时间',
        dataIndex: 'asgnTime',
        className: diffShow,
        // sorter: (a, b) => new Date(b.asgnTime) - new Date(a.asgnTime),
        sorter: true,
        onCell: () => ({
          style: {
            textAlign: 'center',
          },
        }),
        onHeaderCell: () => ({
          style: {
            textAlign: 'center',
            fontWeight: 'bold',
          },
        }),
        render: (text, record) => {
          let name;
          if (record.asgnTime != null) {
            name = moment(record.asgnTime).format('YYYY-MM-DD HH:mm');
          } else {
            name = '--';
          }
          return <span>{name}</span>;
        },
      },
    ];
    const autoColumns = [
      {
        title: '姓名',
        dataIndex: 'tskName',
        onHeaderCell: () => ({
          style: {
            fontWeight: 'bold',
          },
        }),
        render: text => <span>{text}</span>,
      },
      {
        title: '服务对象',
        dataIndex: 'serObjName',
        onCell: () => ({
          style: {
            textAlign: 'center',
          },
        }),
        onHeaderCell: () => ({
          style: {
            textAlign: 'center',
            fontWeight: 'bold',
            width: 170,
          },
        }),
      },
      {
        title: '操作人',
        dataIndex: 'operName',
        onHeaderCell: () => ({
          style: {
            fontWeight: 'bold',
          },
        }),
        render: text => <TextOverFlow text={text} />,
      },
      {
        title: '操作时间',
        dataIndex: 'operTime',
        onCell: () => ({
          style: {
            textAlign: 'center',
          },
        }),
        onHeaderCell: () => ({
          style: {
            textAlign: 'center',
            fontWeight: 'bold',
          },
        }),
        render: (text, record) => {
          let name;
          if (record.operTime != null) {
            name = moment(record.operTime).format('YYYY-MM-DD HH:mm');
          } else {
            name = '--';
          }
          return <span>{name}</span>;
        },
      },
      {
        title: '操作',
        dataIndex: 'operation',
        onHeaderCell: () => ({
          style: { fontWeight: 'bold', textAlign: 'center' },
        }),
        onCell: () => ({ style: { textAlign: 'center' } }),
        render: (text, record) => (
          <span>
            <a onClick={() => this.openDetail(record)}>查看</a>

            <Divider type="vertical" />
            <Dropdown overlay={moreMenu(record)}>
              <a>
                更多 <DownOutlined />
              </a>
            </Dropdown>
          </span>
        ),
      },
    ];
    return { columns, autoColumns };
  };

  getTabPanel = code => {
    const loading = this.props.loading;
    const { list, pagination, selectedRows, selectedRowKeys } = this.props.allocation.tableList;
    const { columns, autoColumns } = this.getTableColumns();
    const data = { list, pagination };
    if (code === 1) {
      return {
        authorityList: [
          {
            authority: 'es:entry:unAllotEntry',
            onClick: this.cancelAlloc,
            type: 'primary',
            title: '取消分配',
          },
        ],
        selectedRows,
        selectedRowKeys,
        loading,
        data,
        rowKey: 'entryId',
        columns,
        onSelectRow: this.props.handleTLSelectRows,
        onChange: this.props.handleTLTableChange,
      };
    }
    if (code === 2) {
      return {
        authorityList: [
          {
            authority: 'es:entry:receiveEntry',
            onClick: this.getType,
            title: '领取',
            style: { marginRight: 8 },
            type: 'primary',
          },
          {
            authority: 'es:entry:allotEntry',
            onClick: this.getAllocats,
            title: '分配',
          },
        ],
        selectedRows,
        selectedRowKeys,
        loading,
        data,
        rowKey: 'entryId',
        columns,
        onSelectRow: this.props.handleTLSelectRows,
        onChange: this.props.handleTLTableChange,
      };
    }
    if (code === 3) {
      return {
        authorityList: [
          {
            authority: 'es:allotRule:addAllotRule',
            onClick: this.addRule,
            title: '添加规则',
            style: { marginRight: 8 },
            type: 'primary',
            children: <PlusOutlined />,
          },
        ],
        selectedRows,
        selectedRowKeys,
        loading,
        data: { ...data },
        // 因为混用了data 会导致报没有key的错误 ,无力修改，暂时不动
        rowKey: 'astAllotRuleId',
        columns: autoColumns,
        onSelectRow: this.props.handleTLSelectRows,
        onChange: this.props.handleTLTableChange,
      };
    }
  };

  // 分配关闭
  handleOk = fieldsValue =>
    new Promise(async (resolve, reject) => {
      const { dispatch, allocation } = this.props;
      const {
        tableList,
        tab: { activeKey },
      } = allocation;
      const { selectedRows } = tableList;
      const { current, pageSize } = tableList.pagination;
      const searchFieldsValue = this.formRef.current.getFieldsValue();
      try {
        const formFieldsValue = this.getDateParam({ ...fieldsValue, ...searchFieldsValue });
        const arr = selectedRows.map(item => ({ entryId: item.entryId, vno: item.vno }));
        const values = {
          entryList: arr,
          tskId: fieldsValue.user && fieldsValue.user.key,
          tskName: fieldsValue.user && fieldsValue.user.label,
          entryInfoQueryDto: {
            asgnState: activeKey,
            ...formFieldsValue,
          },
        };
        const response = await dispatch({
          type: 'allocation/allot',
          payload: values,
        });
        if (response.success) {
          message.success('分配成功！');
          this.handleSearch(current, pageSize);
          this.handleCancel();
        }
        resolve();
      } catch (e) {
        reject(e);
      }
    });

  // 查询列表
  handleSearch = async (current = 1, pageSize = 10, isClear = true) => {
    const { dispatch } = this.props;
    if (isClear) {
      this.props.handleTLClearSelectRows();
    }
    const { orderBy } = this.props.allocation.tableList;
    const { activeKey } = this.props.allocation.tab;

    const fieldsValue = this.formRef.current.getFieldsValue();
    const formFieldsValue = this.getDateParam(fieldsValue);
    const values = {
      ...formFieldsValue,
      asgnState: activeKey,
      pageOrdBys: orderBy,
      pagerArg: { currentPage: current, pageSize },
    };
    dispatch({
      type: 'allocation/setInitialValues',
      payload: {
        initialValues: fieldsValue,
      },
    });
    dispatch({
      type: 'allocation/debounceFetchTableList',
      payload: {
        service: Number(activeKey) === 3 ? getAllotRuleList : allocationList,
        data: values,
      },
    });
  };

  handleDetailOk = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'allocation/updateDetailModalVisible',
      payload: { visible: false },
    });
  };

  handleDetailCancel = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'allocation/updateDetailModalVisible',
      payload: { visible: false },
    });
  };

  handleAutoOk = fieldsValue =>
    new Promise(async (resolve, reject) => {
      try {
        const {
          dispatch,
          allocation: { modifyObj },
        } = this.props;
        const { csFlag, customeFlag } = fieldsValue;
        const inParam = {
          ...fieldsValue,
          newTskId: undefined,
          csFlag: undefined,
          customeFlag: undefined,
          serObj: [csFlag ? 1 : false, customeFlag ? 2 : false].filter(item => item).join(','),
          tskId: fieldsValue.newTskId,
          vno: modifyObj.vno ? modifyObj.vno : undefined,
          astAllotRuleId: modifyObj.astAllotRuleId ? modifyObj.astAllotRuleId : undefined,
        };
        const url = modifyObj.vno ? 'allocation/modifyAllotRule' : 'allocation/addAllotRule';
        const response = await dispatch({
          type: url,
          payload: inParam,
        });
        if (response.success) {
          this.handleModalVisible(false);
          this.handleSearch();
        }
        resolve();
      } catch (e) {
        reject(e);
      }
    });

  handleCancel = () => {
    this.dispatchVisible(false);
  };

  handleAutoCancel = () => {
    this.handleModalVisible(false);
  };

  closeModalCallBack = () => {
    const {
      allocation: { data },
    } = this.props;
    const { current, pageSize } = data.pagination;
    this.handleSearch(current, pageSize);
  };

  // 取消分配
  cancelAlloc = () => {
    const {
      dispatch,
      allocation: { tableList },
    } = this.props;
    const { selectedRows } = tableList;
    const { current, pageSize } = tableList.pagination;
    if (selectedRows.length) {
      const arr = selectedRows.map(item => ({ entryId: item.entryId, vno: item.vno }));
      const values = {
        entryList: arr,
      };
      unAllocConfirm(async () => {
        const response = await dispatch({
          type: 'allocation/unAllot',
          payload: values,
        });
        if (response.success) {
          message.success('取消分配成功！');
          this.handleSearch(current, pageSize);
        }
      });
    } else {
      message.warning('温馨提示：至少选择一条数据！');
    }
  };

  handleModalVisible = async flag => {
    const { dispatch } = this.props;
    await dispatch({
      type: 'allocation/clearAutoFlag',
    });
    await dispatch({
      type: 'allocation/updateModelData',
      payload: {
        autoModalVisible: !!flag,
      },
    });
  };

  // 添加规则
  addRule = () => {
    const { dispatch } = this.props;
    this.handleModalVisible(true);
    dispatch({
      type: 'allocation/updateModelData',
      payload: {
        modifyObj: {},
        actionType: 1,
        csFlag: false,
        customeFlag: false,
      },
    });
  };

  // 修改规则
  updateRule = modifyObj => {
    const { dispatch } = this.props;
    this.handleModalVisible(true);
    dispatch({
      type: 'allocation/updateModelData',
      payload: {
        modifyObj,
        actionType: 2,
        csFlag: modifyObj.creIdList && modifyObj.creIdList.length > 0,
        customeFlag: modifyObj.custIdList && modifyObj.custIdList.length > 0,
      },
    });
  };

  // 查看详情
  openDetail = record => {
    const { dispatch } = this.props;
    dispatch({
      type: 'allocation/updateModelData',
      payload: {
        actionType: 3,
        detailModalVisible: true,
        modifyObj: record,
      },
    });
  };

  // 删除规则
  delRule = record => {
    const { astAllotRuleId, vno } = record;
    const { dispatch } = this.props;
    deleteConfirm(async () => {
      const res = await dispatch({
        type: 'allocation/deleteRule',
        payload: {
          astAllotRuleId,
          vno,
        },
      });
      if (res.success) {
        this.handleSearch();
      }
    });
  };

  dispatchVisible(visible) {
    const { dispatch } = this.props;
    dispatch({
      type: 'allocation/updateModelData',
      payload: { visible },
    });
  }

  renderRuleTitle = () => {
    const {
      allocation: { actionType },
    } = this.props;
    let title = '';
    switch (actionType) {
      case 1:
        title = '添加规则';
        break;
      case 2:
        title = '修改规则';
        break;
      case 3:
        title = '规则详情';
        break;
      default:
    }
    return title;
  };

  renderSearchForm() {
    const {
      allocation: { suppList, searchForm },
    } = this.props;
    const { expand, count, layout, name, gutter, initialValues } = searchForm;
    const dateFormat = 'YYYY-MM-DD';
    const fields = [
      {
        name: 'empName',
        label: '员工姓名',
      },
      {
        name: 'certNo',
        label: '证件号',
      },
      {
        name: 'custId',
        label: '客户名称',
        children: (
          <Customer
            labelInValue
            attr
            allowClear
            showSearch
            filterOption={(input, option) =>
              option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
            }
          />
        ),
      },
      {
        name: 'areaId',
        label: '执行地',
        children: (
          <Area
            labelInValue
            allowClear
            showSearch
            filterOption={(input, option) =>
              option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
            }
          />
        ),
      },
      {
        name: 'creId',
        label: '所属客服',
        children: (
          <SearchPersonEs
            allowClear
            showSearch
            filterOption={(input, option) =>
              option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
            }
          />
        ),
      },
      {
        name: 'tskId',
        label: '办理人',
        children: (
          <SearchPersonEs
            allowClear
            showSearch
            filterOption={(input, option) =>
              option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
            }
          />
        ),
      },
      {
        name: 'dateArr',
        label: '日期',
        rules: [{ type: 'array' }],
        children: (
          <RangePicker
            format={dateFormat}
            placeholder={['开始日期', '结束日期']}
            style={{ width: '100%' }}
          />
        ),
      },
      {
        name: 'sendSuppIds',
        label: '签约方',
        rules: [{ type: 'array' }],
        children: (
          <HOCSelect
            mode="multiple"
            placeholder="请选择"
            optionFilterProp="children"
            notFoundContent="暂无数据"
            showArrow
          >
            {suppList.map(item => (
              <Option key={item.suppId} title={item.name}>
                {item.name}
              </Option>
            ))}
          </HOCSelect>
        ),
      },
    ];

    const props = { fields, count, expand };

    return (
      <Form
        {...layout}
        ref={this.formRef}
        name={name}
        initialValues={initialValues}
        layout="inline"
        onFinish={this.props.handleTLFormOnfinish}
      >
        <Row gutter={gutter}>
          {this.props.renderTLFields(props)}
          {this.props.renderTLFieldsButton()}
        </Row>
      </Form>
    );
  }

  render() {
    const formItemLayout = {
      labelCol: {
        span: 6,
      },
      wrapperCol: {
        span: 17,
      },
    };

    const { allocation } = this.props;
    const {
      visible,
      tab,
      userList,
      esList,
      csList,
      custList,
      autoModalVisible,
      serviceLabel,
      csLabel,
      csFlag,
      customerLabel,
      customeFlag,
      ruleTip,
      actionType,
      modifyObj,
      detailModalVisible,
    } = allocation;
    const { list: tabList, activeKey } = tab;
    const serUserOption = userList.map(email => (
      <Option key={email.userId} value={email.userId}>
        {email.userName}
      </Option>
    ));

    const esListOption = esList.map(email => (
      <Option key={email.userId} value={email.userId}>
        {email.userName}
      </Option>
    ));
    const csListOption = csList.map(email => (
      <Option key={email.userId} value={email.userId}>
        {email.userName}
      </Option>
    ));
    const custListOption = custList.map(email => (
      <Option key={email.custId} value={email.custId}>
        {email.name}
      </Option>
    ));
    return (
      <PageHeaderWrapper>
        <Card className={styles.searchCard}>
          <div className={styles.tableListForm}>{this.renderSearchForm()}</div>
        </Card>
        <Card className={styles.tabCard}>
          <Tabs
            defaultActiveKey={activeKey}
            activeKey={activeKey}
            onChange={this.props.handleTLTabChange}
          >
            {tabList.map(pane => (
              <TabPane tab={pane.itemName} key={pane.itemCode}>
                <TabPanel key={`tabpanel${pane.itemCode}`} {...this.getTabPanel(+pane.itemCode)} />
              </TabPane>
            ))}
          </Tabs>
          <AllocationModal
            visible={visible}
            handleOk={this.handleOk}
            handleCancel={this.handleCancel}
            serUserOption={serUserOption}
            formItemLayout={formItemLayout}
          />
          <DetailModal
            visible={detailModalVisible}
            handleOk={this.handleDetailOk}
            handleCancel={this.handleDetailCancel}
            formItemLayout={formItemLayout}
            serviceLabel={serviceLabel}
            modifyObj={modifyObj}
            csLabel={csLabel}
            customerLabel={customerLabel}
            ruleTip={ruleTip}
          />
          <AutoModal
            title={this.renderRuleTitle()}
            visible={autoModalVisible}
            handleOk={this.handleAutoOk}
            handleCancel={this.handleAutoCancel}
            actionType={actionType}
            formItemLayout={formItemLayout}
            serviceLabel={serviceLabel}
            modifyObj={modifyObj}
            csLabel={csLabel}
            csFlag={csFlag}
            csListOption={csListOption}
            customerLabel={customerLabel}
            customerFlag={customeFlag}
            custListOption={custListOption}
            esListOption={esListOption}
            ruleTip={ruleTip}
          />
        </Card>
      </PageHeaderWrapper>
    );
  }
}
export default TableList;
